home *** CD-ROM | disk | FTP | other *** search
- /*
- * Celestial Mechanics Simulation Tool
- *
- * W. John Guineau
- * 3 Royal Crest Drive #9
- * Marlboro, Mass. 01752
- * (508) 485-6233
- *
- * Files:
- * cm.c
- * cm.h
- * cm.doc
- *
- * To Compile with Lattice 5.02:
- *
- * lc -b0 -Lm cm
- *
- *
- * NOTICE
- * ------
- *
- * I have placed this software in the Public Domain with the
- * condition that all the files remain together and that I remain
- * listed as the original author. This software may not be used for
- * commercial purposes or to make money in any way without expressed
- * written permission from the author (me). I'm including the source
- * code so if you make any significant modifications please concider
- * sending me a copy at the above address. I'd also be interested in
- * any interesting saved setup files you create.
- *
- *
- * This is my first Amiga program so I welcome any comments at all.
- * I wrote this program as both a way to learn the Amiga environment
- * and in response to a conversation I had with a friend on Celestial
- * Mechanics.
- *
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
-
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/devices.h>
- #include <libraries/dosextens.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/rastport.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gfx.h>
- #include <graphics/display.h>
- #include <graphics/text.h>
-
-
-
-
- #include "cm.h"
-
-
-
- #define NOWAIT 0
- #define WAIT 1
-
-
- extern struct IntuitionBase *IntuitionBase;
- extern struct GfxBase *GfxBase;
- struct IntuiMessage *message;
-
- struct Screen *s;
- struct Window *w;
- struct Window *pw;
- struct RastPort *rp;
- struct RastPort *prp;
- struct ViewPort *vp;
-
-
- #define ReqNone 0
- #define ReqBody 1
- #define ReqSetup 2
- #define ReqFile 3
- #define ReqAbout 4
-
-
- UBYTE CancelHit=0; /* If user selects CANCEL from Reqester */
- UBYTE ReqActive=ReqNone; /* Set when a Reqester is active */
- /* to keep DoIntuiEvents() from returning */
- /* until it gets a REQCLEAR msg */
-
-
- struct setup {
- double G;
- double ds;
- double dt;
- UBYTE t;
- WORD TrailLength;
- UBYTE ShowTime;
- } SI;
-
- #define MAXTRAILEN 300
-
- struct Body { /* Info for a Celestial Body */
- UBYTE real; /* If it's real */
- UBYTE fixed; /* Body fixed in place */
- UBYTE pen; /* Color Register */
- char name[10]; /* user given name */
- ULONG Radius; /* radius */
- double Mass; /* mass */
- double x,y; /* current position */
- double Vx,Vy; /* velocity components */
- double Fx,Fy; /* resultant force components */
- double Dir; /* direction angle (radians) */
- double TrailX[MAXTRAILEN]; /* X of trail of pixels to clear */
- double TrailY[MAXTRAILEN]; /* X of trail of pixels to clear */
- WORD TrailIDX;
- };
-
-
- #define MAXBODYS 10
- struct Body Bodys[MAXBODYS]; /* The array of bodys */
- BYTE CurBody,TotalBodys=0;
-
- ULONG Et; /* elapsed time */
-
-
- #define MODE_CREATE 1
- #define MODE_MODIFY 2
- #define MODE_START 3
- #define MODE_STOP 4
- UBYTE mode = MODE_STOP; /* Current simulation mode */
-
-
-
-
- /* pointer text for ShowMouse() */
- char pbuf[80];
- struct IntuiText pos_txt = {
- WHTPEN,BLKPEN, /* FrontPen, BackPen */
- JAM2, /* DrawMode */
- 7,2, /* LeftEdge, TopEdge */
- &TxtAt_Plain, /* TextAttr */
- pbuf, /* IText */
- NULL /* NextText */
- };
-
-
-
- struct MsgPort *TimerPort; /* for Timer stuff */
- struct timerequest *TR;
- UBYTE TimerOpen=0;
-
-
-
-
-
- /* ============================================================
- * Main
- *
- * ============================================================*/
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
-
- OpenStuff();
- Init();
-
- DoIntuiEvents(WAIT);
-
- return(0);
-
- }
-
-
-
-
-
-
-
-
-
- OpenStuff()
- {
-
- TimerPort = (struct MsgPort *)CreatePort(0,0);
- if(TimerPort == 0) {
- printf("Cant get a Timer Port\n");
- CleanUp();
- exit(10);
- };
-
- TR = (struct timerequest *)CreateExtIO(TimerPort,
- sizeof(struct timerequest));
- if(TR == 0) {
- printf("Cant get a Timer Request\n");
- CleanUp();
- exit(11);
- };
-
-
- if(OpenDevice(TIMERNAME,UNIT_VBLANK,TR,0) != 0) {
- printf("Cant open Timer Device\n");
- CleanUp();
- exit(12);
- };
- TimerOpen = 1;
-
-
- if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) {
- printf("no graphics library!!!\n");
- CleanUp();
- exit(13);
- };
-
- if(!(IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library",0))) {
- printf("no intuition here!!\n");
- CleanUp();
- exit(14);
- };
-
-
-
- if (!(s = (struct Screen *)OpenScreen(&ns) )) {
- printf("could not open the screen\n");
- CleanUp();
- exit(15);
- };
-
-
- /*
- * set up color map for new screen
- */
- vp = (struct ViewPort *)&s->ViewPort;
- LoadRGB4(vp,colortable,COLORS);
-
- nw.Screen = s; /* point to our screen */
- npw.Screen = s; /* pointer window struct also */
-
- if (!(w = (struct Window *)OpenWindow(&nw) )) {
- printf("could not open the window\n");
- CleanUp();
- exit(16);
- };
-
- rp = w->RPort;
- SetAPen(rp,WHTPEN);
-
- SetMenuStrip(w,&Control);
-
- return(0);
-
- }
-
-
-
- Init()
- {
-
- SI.G = 6.67;
- SI.ds = 1.0;
- SI.dt = 1.0;
- SI.t = 0;
- SI.TrailLength = 0;
-
- cancel_text.IText = cantxt;
-
- OffMenu(w,MN_CStop);
- OffMenu(w,MN_EMod);
- OffMenu(w,MN_FSScr);
-
-
- ClearScreen();
- ClearBodys();
- SetupGADefaults();
- BodyGADefaults();
-
- return(0);
-
- }
-
-
-
-
- ClearScreen()
- {
-
- SetRast(rp,0);
-
- SetAPen(rp,WHTPEN);
-
- return(0);
-
- }
-
-
- DoIntuiEvents(wait)
- UBYTE wait;
- {
- ULONG MessageClass;
- USHORT code,qual;
- struct Gadget *GAD;
- struct MsgPort *mp;
-
- mp = w->UserPort;
-
- for(;;) {
-
- if(message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
-
- MessageClass = message->Class;
- code = message->Code;
- qual = message->Qualifier;
- GAD = (struct Gadget *)message->IAddress;
-
- ReplyMsg(message);
-
- switch (MessageClass) {
-
- case GADGETUP : DoGadget(GAD);
- break;
-
- case MENUPICK : if(code != MENUNULL) {
- DoMenu(code);
- };
- break;
-
- case CLOSEWINDOW : CleanUp();
- exit(0);
- break;
-
- case MOUSEBUTTONS: if(code == SELECTDOWN) {
- MakeBody(w->GZZMouseX,w->GZZMouseY);
- };
- break;
-
- case MOUSEMOVE : if(mode == MODE_CREATE) {
- ShowMouse(w->GZZMouseX,w->GZZMouseY);
- };
- break;
-
- case REQCLEAR :
- ReqActive = ReqNone;
- break;
-
- default :
- break;
-
- };
-
- } else {
-
- if(!wait&&!ReqActive) return(0);
-
- WaitPort(mp);
-
- };
-
- };
- return(0);
- }
-
-
-
- DoGadget(GAD)
- struct Gadget *GAD;
- {
- ULONG val;
- struct StringInfo *info;
-
-
- info = (struct StringInfo *)GAD->SpecialInfo;
- val = info->LongInt;
-
- switch(GAD->GadgetID) {
-
- case NAMEGAD :
- ActivateGadget(&mass,w,&BodyInfo);
- break;
- case RADIUSGAD :
- break;
-
- case MASSGAD :
- ActivateGadget(&velocity,w,&BodyInfo);
- break;
-
- case VELOCITYGAD :
- ActivateGadget(&direction,w,&BodyInfo);
- break;
-
- case DIRECTIONGAD :
- break;
-
- case OKGAD :
- CancelHit=0;
- if(pw)
- WindowToFront(pw);
- break;
-
- case CANCELGAD :
- CancelHit=1;
- if(pw)
- WindowToFront(pw);
- break;
-
- case RESETGAD :
- switch(ReqActive) {
- case ReqBody : BodyGADefaults();
- RefreshGadgets(&mass,
- w,&BodyInfo);
- break;
- case ReqSetup : SetupGADefaults();
- RefreshGadgets(&dt,
- w,&SetupInfo);
- break;
-
- };
- break;
-
- case GGAD :
- ActivateGadget(&dt,w,&SetupInfo);
- break;
-
- case DTGAD :
- ActivateGadget(&t,w,&SetupInfo);
- break;
-
- case TGAD :
- ActivateGadget(&ds,w,&SetupInfo);
- break;
-
- case DSGAD :
- ActivateGadget(&tl,w,&SetupInfo);
- break;
-
- case TLGAD :
- break;
-
- case COLOR1GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case COLOR2GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case COLOR3GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case COLOR4GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case COLOR5GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case COLOR6GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case COLOR7GAD :
- Bodys[CurBody].pen = (UBYTE)GAD->UserData;
- break;
- case FNOKGAD :
- CancelHit=0;
- break;
- case FNCANGAD :
- CancelHit=1;
- break;
- case STGAD : if(st.Flags&SELECTED) {
- st.GadgetText = &yes_text;
- RefreshGadgets(&st,w,&SetupInfo);
- SI.ShowTime=1;
- } else {
- st.GadgetText = &no_text;
- RefreshGadgets(&st,w,&SetupInfo);
- SI.ShowTime=0;
- };
- break;
- case FXGAD : if(fixed.Flags&SELECTED) {
- fixed.GadgetText = &yes_text;
- RefreshGadgets(&fixed,w,&BodyInfo);
- Bodys[CurBody].fixed=1;
- } else {
- fixed.GadgetText = &no_text;
- RefreshGadgets(&fixed,w,&BodyInfo);
- Bodys[CurBody].fixed=0;
- };
- break;
-
- default :
- break;
-
- };
-
- return(0);
- }
-
-
-
- DoMenu(MN)
- USHORT MN;
- {
-
- switch(MENUNUM(MN)) {
-
- case M_Control :
- switch(ITEMNUM(MN)) {
-
- case I_Stop :
- mode = MODE_STOP;
- ClosePw();
- OffMenu(w,MN_CStop);
- OnMenu(w,MN_ECreate);
- OnMenu(w,MN_ESetup);
- OnMenu(w,MN_EMod);
- OnMenu(w,MN_EClearS);
- OnMenu(w,MN_EClearB);
- OnMenu(w,MN_FSDat);
- OnMenu(w,MN_FLDat);
- OnMenu(w,MN_CStart);
- break;
- case I_Start :
- if(TotalBodys == 0) {
- MSG("No Bodys Created!!","OK","OK");
- break;
- };
- mode = MODE_START;
- ModifyIDCMP(w,IDCMPFL);
- if(SI.ShowTime) OpenPw();
- OffMenu(w,MN_ECreate);
- OffMenu(w,MN_ESetup);
- OffMenu(w,MN_EMod);
- OffMenu(w,MN_CStart);
- OffMenu(w,MN_EClearS);
- OffMenu(w,MN_EClearB);
- OffMenu(w,MN_FSDat);
- OffMenu(w,MN_FLDat);
- OnMenu(w,MN_CStop);
- DoSimulation();
- break;
- };
- break;
-
- case M_Edit :
- switch(ITEMNUM(MN)) {
-
- case I_ClearB : if(MSG("Really Clear Bodys?",
- "YES!","NO!!")) {
- ClearBodys();
- OnMenu(w,MN_FSDat);
- OnMenu(w,MN_FLDat);
- };
-
- break;
- case I_ClearS :
- ClearScreen();
- break;
- case I_Modify :
- mode = MODE_MODIFY;
- ModifyBodys();
- break;
- case I_Create :
- mode = MODE_CREATE;
- ModifyIDCMP(w,IDCMPFL_MM);
- OpenPw();
- OnMenu(w,MN_CStart);
- OnMenu(w,MN_EMod);
- OffMenu(w,MN_ECreate);
- OffMenu(w,MN_FLDat);
- cancel_text.IText = cantxt;
- break;
- case I_Setup :
- Request(&SetupInfo,w);
- Sleep(0L,100000L);
- ActivateGadget(&G,w,&SetupInfo);
- ReqActive = ReqSetup;
- DoIntuiEvents(NOWAIT);
- cancel_text.IText = cantxt;
- if(!CancelHit) GetSetupInfo();
- break;
- };
- break;
-
- case M_File :
- switch(ITEMNUM(MN)) {
-
- case I_Exit :
- CleanUp();
- exit(0);
- break;
- case I_SavScr :
- break;
- case I_SavDat :
- DoSaveData();
- break;
- case I_LoadDat :
- DoLoadData();
- break;
- case I_About :
- Request(&RAbout,w);
- ReqActive = ReqAbout;
- DoIntuiEvents(NOWAIT);
- break;
- };
- break;
-
- };
-
- return(0);
-
- }
-
-
-
- ShowMouse(x,y)
- SHORT x,y;
- {
-
- if(x<0||y<0) return(0);
-
- sprintf(pbuf," %.3e , %.3e",
- (double)(x)*SI.ds,(double)(w->GZZHeight-y+1)*SI.ds);
- PrintIText(prp,&pos_txt,0,0);
-
- return(0);
- }
-
- OpenPw()
- {
-
- if(pw) return(0);
-
- if (!(pw = (struct Window *)OpenWindow(&npw) )) {
- printf("could not open the pointer window\n");
- CleanUp();
- exit(17);
- };
-
- prp = pw->RPort;
- SetAPen(prp,BLKPEN);
- SetBPen(prp,WHTPEN);
-
- return(0);
-
- }
-
- ClosePw()
- {
- if(pw) CloseWindow(pw);
- pw = (struct Window *)NULL;
- return(0);
- }
-
-
-
- GetBodyInfo()
- {
- double V;
-
-
- strcpy(Bodys[CurBody].name,name_sbuf);
-
- if(sscanf(mass_sbuf,"%le",&Bodys[CurBody].Mass) != 1) {
- MSG("Bad Value for Mass!","OK","OK");
- return(0);
- };
-
- Bodys[CurBody].Dir =
- (double)direction_txstr.LongInt * PI/180.0;
-
- if(sscanf(velocity_sbuf,"%le",&V) != 1) {
- MSG("Bad Value for Velocity!","OK","OK");
- return(0);
- };
-
- Bodys[CurBody].Vx =
- V * cos(Bodys[CurBody].Dir);
- Bodys[CurBody].Vy =
- V * sin(Bodys[CurBody].Dir);
-
- if(Bodys[CurBody].pen == 0)
- Bodys[CurBody].pen = WHTPEN;
-
- Bodys[CurBody].Fx = 0.0;
- Bodys[CurBody].Fy = 0.0;
-
-
- return(0);
- }
-
-
-
-
-
- GetSetupInfo()
- {
- WORD n;
-
- if(sscanf(G_sbuf,"%le",&SI.G) != 1) {
- MSG("Bad Value for G!","OK","OK");
- return(0);
- };
-
- if(sscanf(ds_sbuf,"%le",&SI.ds) != 1) {
- MSG("Bad Value for ds!","OK","OK");
- return(0);
- };
-
- if(sscanf(dt_sbuf,"%le",&SI.dt) != 1) {
- MSG("Bad Value for dt!","OK","OK");
- return(0);
- };
-
- SI.t = (UBYTE)t_txstr.LongInt;
-
- n = (WORD)tl_txstr.LongInt;
- if(n>MAXTRAILEN) {
- MSG("TrailLength too large!","OK","OK");
- return(0);
- };
-
- SI.TrailLength=n;
-
- return(0);
- }
-
-
-
-
- MakeBody(x,y)
- SHORT x,y;
- {
-
-
- if(mode != MODE_CREATE)
- return(0);
- if(x<0 || y<0)
- return(0);
-
- if(TotalBodys++ > MAXBODYS) {
- TotalBodys--;
- MSG("No More Body's Available!!","OK","OK");
- return(0);
- };
-
- SetAPen(rp,REDPEN);
- WritePixel(rp,x,y);
- CurBody = FindFreeBody();
- if(CurBody == -1) {
- TotalBodys--;
- MSG("No More Body's Available!!","OK","OK");
- return(0);
- };
- cancel_text.IText = cantxt;
-
- BodyGADefaults();
- sprintf(xy_buf," %.3e , %.3e ",
- (double)(x)*SI.ds,(double)(w->GZZHeight-y+1)*SI.ds);
- Request(&BodyInfo,w);
- ReqActive = ReqBody;
- Sleep(0L,100000L);
- ActivateGadget(&name,w,&BodyInfo);
- DoIntuiEvents(NOWAIT);
-
- if(CancelHit) {
- TotalBodys--;
- SetAPen(rp,BLKPEN);
- WritePixel(rp,x,y);
- return(0);
- };
-
- GetBodyInfo();
-
- if(Bodys[CurBody].Mass == 0.0) {
- TotalBodys--;
- SetAPen(rp,BLKPEN);
- WritePixel(rp,x,y);
- MSG("Mass can't be ZERO!!","OK","OK");
- return(0);
- };
-
- Bodys[CurBody].x = (double)(x)*SI.ds;
- Bodys[CurBody].y = (double)(y)*SI.ds;
- Bodys[CurBody].real = 1;
- SetAPen(rp,Bodys[CurBody].pen);
- WritePixel(rp,x,y);
-
- return(0);
-
- }
-
- FindFreeBody()
- {
- int x;
-
- for(x=0 ; x<MAXBODYS ; x++)
- if(!Bodys[x].real) return(x);
-
- return(-1);
-
- }
-
-
- ModifyBodys()
- {
- int n;
- SHORT x,y;
-
-
- mode = MODE_MODIFY;
- ModifyIDCMP(w,IDCMPFL);
- ClosePw();
- OffMenu(w,MN_CStart);
- OffMenu(w,MN_EMod);
- OffMenu(w,MN_ECreate);
- cancel_text.IText = deltxt;
-
-
- for(n=0 ; n<MAXBODYS ; n++) {
-
- CurBody = n;
- if(Bodys[n].real) {
-
- Bodys[n].real=0;
-
- LoadBodyReq(n);
- x = (SHORT)(Bodys[n].x/SI.ds);
- y = (SHORT)(Bodys[n].y/SI.ds);
-
- color_text.FrontPen = Bodys[n].pen;
- sprintf(xy_buf," %.3e , %.3e ",
- (double)(x)*SI.ds,(double)(w->GZZHeight-y+1)*SI.ds);
- Request(&BodyInfo,w);
- Sleep(0L,100000L);
- ReqActive = ReqBody;
- ActivateGadget(&name,w,&BodyInfo);
- DoIntuiEvents(NOWAIT);
-
- if(CancelHit) { /* GAD really says "DELETE" */
- TotalBodys--;
- SetAPen(rp,BLKPEN);
- WritePixel(rp,x,y);
- continue;
- };
-
- GetBodyInfo();
-
- if(Bodys[n].Mass == 0.0) {
- TotalBodys--;
- SetAPen(rp,BLKPEN);
- WritePixel(rp,(SHORT)x,(SHORT)y);
- MSG("Mass can't be ZERO!!","OK","OK");
- continue;
- };
-
- Bodys[n].real=1;
- SetAPen(rp,Bodys[CurBody].pen);
- WritePixel(rp,x,y);
-
- };
- };
-
-
- color_text.FrontPen = WHTPEN;
-
- OnMenu(w,MN_CStart);
- OnMenu(w,MN_ECreate);
- if(TotalBodys)
- OnMenu(w,MN_EMod);
- else
- OffMenu(w,MN_EMod);
-
- return(0);
-
- }
-
-
-
- LoadBodyReq(n)
- int n;
- {
- double v;
-
- name_txstr.NumChars = sprintf(name_sbuf,"%s",Bodys[n].name);
- mass_txstr.NumChars = sprintf(mass_sbuf,"%.3e",Bodys[n].Mass);
-
- direction_txstr.LongInt = (ULONG)(Bodys[n].Dir * 180.0/PI);
- direction_txstr.NumChars = sprintf(direction_sbuf,"%ld",
- direction_txstr.LongInt);
-
- v = Bodys[n].Vx*Bodys[n].Vx + Bodys[n].Vy*Bodys[n].Vy;
- v = sqrt(v);
- velocity_txstr.NumChars = sprintf(velocity_sbuf,"%.3e",v);
-
- if(Bodys[n].fixed) {
- fixed.GadgetText = &yes_text;
- fixed.Flags |= SELECTED;
- } else {
- fixed.GadgetText = &no_text;
- fixed.Flags &= ~SELECTED;
- }
-
- return(0);
- }
-
-
-
-
- DoSimulation()
- {
- UBYTE b;
- double F,Fx=0.0,Fy=0.0,V;
-
-
- Et = 0L;
-
- while(mode == MODE_START) {
-
- if(SI.ShowTime) {
- sprintf(pbuf," Time %ld",Et);
- PrintIText(prp,&pos_txt,0,0);
- };
-
- /*
- * Calculate new directions & velocities
- * resulting from all external forces (all other bodies)
- */
-
- for(b=0 ; b<MAXBODYS ; b++ ) {
-
- if(!Bodys[b].real) continue;
- if(Bodys[b].fixed) continue;
-
- GetForces(b,&Fx,&Fy);
-
- if(Fx != 0.0 && Fy != 0.0) {
-
- F = sqrt(Fx*Fx+Fy*Fy); /* Total force on this body */
- /* indirection of A */
- V = F*SI.dt/Bodys[b].Mass; /* FT = MV (impulse) */
-
- Bodys[b].Vx += V*Fx/F; /* Fx/F = cos(A). adj vel as a result of impulse */
- Bodys[b].Vy += V*Fy/F; /* Fy/F = sin(A). in direction of resultant Force */
-
- Bodys[b].Dir = atan2(Bodys[b].Vy,Bodys[b].Vx); /* new direction */
- if(Bodys[b].Dir < 0.0)
- Bodys[b].Dir += 2.0*PI;
- };
-
-
- };
-
- /*
- * Display new positions
- */
-
- for(b=0 ; b<MAXBODYS ; b++) {
-
- if(!Bodys[b].real) continue;
-
- if(!SI.TrailLength) {
- SetAPen(rp,BLKPEN);
- WritePixel(rp,(SHORT)(Bodys[b].x/SI.ds),(SHORT)(Bodys[b].y/SI.ds));
- } else {
- if(SI.TrailLength>0) {
- if(Bodys[b].TrailIDX >= SI.TrailLength)
- Bodys[b].TrailIDX=0;
- if(Bodys[b].TrailX[Bodys[b].TrailIDX]>=0) {
- SetAPen(rp,BLKPEN);
- WritePixel(rp,(SHORT)(Bodys[b].TrailX[Bodys[b].TrailIDX]/SI.ds),
- (SHORT)(Bodys[b].TrailY[Bodys[b].TrailIDX]/SI.ds));
-
- };
- Bodys[b].TrailX[Bodys[b].TrailIDX] = Bodys[b].x;
- Bodys[b].TrailY[Bodys[b].TrailIDX] = Bodys[b].y;
- Bodys[b].TrailIDX++;
- };
- };
-
- Bodys[b].x += (Bodys[b].Vx * SI.dt);
- Bodys[b].y -= (Bodys[b].Vy * SI.dt);
-
- SetAPen(rp,Bodys[b].pen);
- WritePixel(rp,(SHORT)(Bodys[b].x/SI.ds),(SHORT)(Bodys[b].y/SI.ds));
-
- };
-
- DoIntuiEvents(NOWAIT);
-
- if(SI.t)
- Sleep(0L,(ULONG)SI.t*1000L);
-
- Et++;
-
- };
-
- return(0);
- }
-
-
- GetForces(b,fx,fy)
- UBYTE b;
- double *fx,*fy;
- {
- int x;
- double dY,dX,Fx,Fy,F,R;
-
- Fx = Fy = 0.0;
- for(x=0 ; x<MAXBODYS ; x++) {
-
- if(x==b) continue;
- if(!Bodys[x].real) continue;
-
- dX = (Bodys[x].x - Bodys[b].x) * SI.ds; /* X2 - X1 */
- dY = (Bodys[b].y - Bodys[x].y) * SI.ds; /* Y2 - Y1 BUT */
- /* normalized to bottom */
- /* left of window */
-
- R = dX*dX+dY*dY; /* part of sqrt(x^2+y^2) */
- /* for F calc below. F needs R^2 so we'll */
- /* do sqrt() part after (sqrt(x)^2 = x) */
-
- F = SI.G * (Bodys[b].Mass * Bodys[x].Mass) / R;
-
- R = sqrt(R); /* distance between points */
-
- Fx += F*(dX/R); /* dX/R = cos(A) but faster */
- Fy += F*(dY/R); /* dY/R = sin(A) but faster */
-
- };
-
- *fx = Fx;
- *fy = Fy;
-
- return(0);
- }
-
-
- SetupGADefaults()
- {
-
- strcpy(G_sbuf,"6.67e0");
- G_txstr.NumChars=6;
-
- strcpy(t_sbuf,"0");
- t_txstr.NumChars=1;
- t_txstr.LongInt = 0L;
-
- strcpy(ds_sbuf,"1.0e0");
- ds_txstr.NumChars=5;
-
- strcpy(dt_sbuf,"1.0e0");
- dt_txstr.NumChars=5;
-
- strcpy(tl_sbuf,"0");
- dt_txstr.NumChars=1;
-
- st.GadgetText = &no_text;
- st.Flags &= ~SELECTED;
-
- return(0);
-
- }
-
-
- BodyGADefaults()
- {
-
- strcpy(name_sbuf,"SUN");
- name_txstr.NumChars=3;
-
- strcpy(mass_sbuf,"1.0e0");
- mass_txstr.NumChars=5;
-
- strcpy(velocity_sbuf,"0.0e0");
- velocity_txstr.NumChars=5;
-
- strcpy(direction_sbuf,"0");
- direction_txstr.NumChars=1;
- direction_txstr.LongInt = 0L;
-
- fixed.GadgetText = &no_text;
- fixed.Flags &= ~SELECTED;
-
- return(0);
-
- }
-
-
-
- ClearBodys()
- {
- int x,t;
-
- for(x=0 ; x<MAXBODYS ; x++) {
- Bodys[x].real = 0;
- Bodys[x].pen = 0;
-
- for(t=0 ; t<MAXTRAILEN ; t++) {
- Bodys[x].TrailX[t]=-1.0;
- Bodys[x].TrailY[t]=-1.0;
- };
- Bodys[x].TrailIDX = 0;
-
- };
-
- ClearScreen();
- TotalBodys = 0;
-
- return(0);
-
- }
-
-
-
- DoSaveData()
- {
- int x;
- FILE *fp;
-
-
- Request(&FileName,w);
- Sleep(0L,100000L);
- ActivateGadget(&fn,w,&FileName);
- ReqActive = ReqFile;
- DoIntuiEvents(NOWAIT);
-
- if(CancelHit)
- return(0);
-
-
- fp = fopen(fn_sbuf,"w");
- if(!fp) {
- MSG("Can't open output file!","OK!","OH WELL!");
- return(0);
- };
-
- fprintf(fp,"--- CM Setup Data ---\n");
- fprintf(fp,"G=%.3e\n",SI.G);
- fprintf(fp,"ds=%.3e\n",SI.ds);
- fprintf(fp,"dt=%.3e\n",SI.dt);
- fprintf(fp,"t=%d\n",(int)SI.t);
- fprintf(fp,"TrailLength=%d\n",(int)SI.TrailLength);
- fprintf(fp,"ShowTime=%d\n",(int)SI.ShowTime);
-
-
- fprintf(fp,"--- CM Body Data ---\n");
- fprintf(fp,"#=name ;pen;fixed;Radius;Mass;x,y;Vx,Vy;Dir\n");
- for(x=0 ; x<MAXBODYS ; x++)
- if(Bodys[x].real) {
- fprintf(fp,"%d=%s ;%d;%d;%ld;%.3e;%.3e,%.3e;%.3e,%.3e;%.3e\n",
- x,
- Bodys[x].name,
- (int)Bodys[x].pen,
- (int)Bodys[x].fixed,
- Bodys[x].Radius,
- Bodys[x].Mass,
- Bodys[x].x,w->GZZHeight-Bodys[x].y+1,
- Bodys[x].Vx,Bodys[x].Vy,
- Bodys[x].Dir*180.0/PI);
-
- };
-
- fclose(fp);
-
- return(0);
-
- }
-
-
-
- DoLoadData()
- {
- int n;
- FILE *fp;
- char buf[101],name[10];
- ULONG pen,fixed,Radius;
- double x,y,Mass,Vx,Vy,Dir;
-
-
- CancelHit=0;
- Request(&FileName,w);
- Sleep(0L,100000L);
- ActivateGadget(&fn,w,&FileName);
- ReqActive = ReqFile;
- DoIntuiEvents(NOWAIT);
-
- if(CancelHit)
- return(0);
-
-
- fp = fopen(fn_sbuf,"r");
- if(!fp) {
- MSG("Can't open Data File!","OK!","OH WELL!");
- return(0);
- };
-
- fgets(buf,100,fp); /* forget first line, it's just a header */
- fgets(buf,100,fp);
- if(sscanf(buf,"G=%le\n",&SI.G) != 1) {
- MSG("Bad data file (G)!","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
-
- fgets(buf,100,fp);
- if(sscanf(buf,"ds=%le\n",&SI.ds) != 1) {
- MSG("Bad data file (ds)!","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
-
- fgets(buf,100,fp);
- if(sscanf(buf,"dt=%le\n",&SI.dt) != 1) {
- MSG("Bad data file (dt)!","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
-
- fgets(buf,100,fp);
- if(sscanf(buf,"t=%d\n",&n) != 1) {
- MSG("Bad data file (t)!","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
- SI.t = (UBYTE)n;
-
- fgets(buf,100,fp);
- if(sscanf(buf,"TrailLength=%d\n",&n) != 1) {
- MSG("Bad data file (TrailLength)!","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
-
- if(n>MAXTRAILEN) {
- MSG("TrailLength too big","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
- SI.TrailLength = (WORD)n;
-
- fgets(buf,100,fp);
- if(sscanf(buf,"ShowTime=%d\n",&n) != 1) {
- MSG("Bad data file (ShowTime)!","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
- SI.ShowTime = (WORD)n;
- if(n) {
- st.GadgetText = &yes_text;
- st.Flags |= SELECTED;
- } else {
- st.GadgetText = &no_text;
- st.Flags &= ~SELECTED;
- };
-
-
- G_txstr.NumChars = sprintf(G_sbuf,"%.3e",SI.G);
- dt_txstr.NumChars = sprintf(dt_sbuf,"%.3e",SI.dt);
- t_txstr.NumChars = sprintf(t_sbuf,"%d",SI.t);
- t_txstr.LongInt = (ULONG)SI.t;
- ds_txstr.NumChars = sprintf(ds_sbuf,"%.3e",SI.ds);
- tl_txstr.LongInt = (LONG)SI.TrailLength;
- tl_txstr.NumChars = sprintf(tl_sbuf,"%d",SI.TrailLength);
-
- ClearBodys();
-
- fgets(buf,100,fp);
- fgets(buf,100,fp);
-
- while(fgets(buf,100,fp) != (char *)NULL) {
- if(sscanf(buf,"%d=%s;%d;%d;%ld;%le;%le,%le;%le,%le;%le",
- &n,name,&pen,&fixed,&Radius,&Mass,&x,&y,&Vx,&Vy,&Dir) != 11) {
- MSG("Bad Body in data file","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
- if(n>MAXBODYS) {
- MSG("Bad Body # in data file","OK!","OOPS!");
- fclose(fp);
- return(0);
- };
-
- if(!Bodys[n].real) TotalBodys++; /* don't count same definition twice */
- Bodys[n].real = 1;
- Bodys[n].pen = pen;
- Bodys[n].fixed = fixed;
- Bodys[n].Radius = Radius;
- Bodys[n].Mass = Mass;
- Bodys[n].x = x;
- Bodys[n].y = w->GZZHeight-y+1;
- Bodys[n].Vx = Vx;
- Bodys[n].Vy = Vy;
- Bodys[n].Dir = Dir*PI/180.0;
- strcpy(Bodys[n].name,name);
-
- SetAPen(rp,pen);
- WritePixel(rp,(SHORT)(Bodys[n].x/SI.ds),(SHORT)(Bodys[n].y/SI.ds));
-
- };
-
- fclose(fp);
-
- OnMenu(w,MN_ECreate);
- OnMenu(w,MN_EMod);
-
-
- return(0);
-
- }
-
-
- MSG(msg,p,n)
- char *msg,*p,*n;
- {
-
- struct IntuiText msg_txt = {
- BLKPEN,REDPEN, /* FrontPen, BackPen */
- JAM1, /* DrawMode */
- 10,20, /* LeftEdge, TopEdge */
- &TxtAt_Plain, /* TextAttr */
- 0, /* IText */
- NULL /* NextText */
- };
-
- struct IntuiText pos_txt = {
- BLKPEN,REDPEN, /* FrontPen, BackPen */
- JAM1, /* DrawMode */
- 3,3, /* LeftEdge, TopEdge */
- &TxtAt_Plain, /* TextAttr */
- 0, /* IText */
- NULL /* NextText */
- };
-
- struct IntuiText neg_txt = {
- BLKPEN,REDPEN, /* FrontPen, BackPen */
- JAM1, /* DrawMode */
- 3,3, /* LeftEdge, TopEdge */
- &TxtAt_Plain, /* TextAttr */
- 0, /* IText */
- NULL /* NextText */
- };
-
- msg_txt.IText = msg;
- pos_txt.IText = p;
- neg_txt.IText = n;
-
-
- return(AutoRequest(w,&msg_txt,&pos_txt,&neg_txt,
- NULL,NULL,40+IntuiTextLength(&msg_txt),80));
-
- }
-
-
-
-
-
-
- Sleep(secs,usecs)
- ULONG secs,usecs;
- {
-
- TR->tr_node.io_Command = TR_ADDREQUEST;
- TR->tr_time.tv_secs = secs;
- TR->tr_time.tv_micro = usecs;
- DoIO(TR);
-
- return(0);
-
- }
-
-
-
-
-
- CleanUp()
- {
-
- if(TimerPort) DeletePort(TimerPort);
- if(TimerOpen) CloseDevice(TR);
- if(TR) DeleteExtIO(TR,sizeof(struct timerequest));
- if(w) {
- ClearMenuStrip(w);
- CloseWindow(w);
- };
- if(pw) CloseWindow(pw);
- if(s) {
- CloseScreen(s);
- /* FreeColorMap(cm); */
- };
- if(GfxBase) CloseLibrary(GfxBase);
- (void)OpenWorkBench();
- if(IntuitionBase) CloseLibrary(IntuitionBase);
- return(0);
- }
-
-
-
-
-
-
-
-
-
-
-